type StringNumberPair = [string, number];

// `StringNumberPair` 类型换成接口声明类似这样（但不完全一样）
interface StringNumberPair2 {
    // specialized properties
    length: 2,
    0: string,
    1: number,

    // Other 'Array<string | number>' members...
    slice(start?: number, end?: number): Array<string | number>
}

function doSomeThing(pair: StringNumberPair) {
    const a = pair[0]; // const a: string
    const b = pair[1]; // const b: number
    // 长度为 "2" 的元组类型 "StringNumberPair" 在索引 "2" 处没有元素。
    // const c = pair[2];
}

type Either2Or3 = [number, number, number?];

function setCoordinate(coord: Either2Or3) {
    const [x, y, z] = coord;

    z; // const z: number | undefined

    
    console.log(`Provided coordinates had ${
        coord.length // (property) length: 2 | 3
    } dimensions.`);
}


type StringNumberBooleans = [string, number, ...boolean[]];
type StringBooleansNumber = [string, ...boolean[], number];
type BooleansStringNumber = [...boolean[], string, number];

const a: StringNumberBooleans = ['hello', 1];
const b: StringNumberBooleans = ['beautiful', 2, true];
const c: StringNumberBooleans = ['world', 3, true, false, true, false, true];

function readButtonInput(...args: StringNumberBooleans) {
    const [name, version, ...input] = args;
    // ...
}

// 等价于

function readButtonInput2(name: string, version: number, ...input: boolean[]) {
    // ...
}

function doSomeThing2(pair: readonly [string, number]) {
    // pair[0] = "hello!"; // 无法分配到 "0" ，因为它是只读属性。
}

let point = [3, 4] as const; // let point: readonly [3, 4]